package com.edu.exam.entity.examination.control;

import com.edu.exam.enums.examination.control.AssessmentStatus;
import com.edu.exam.enums.examination.control.TreatmentStrategy;
import com.edu.exam.enums.examination.control.UrgencyLevel;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import java.math.BigDecimal;
import java.time.LocalDateTime;

/**
 * 风险评估实体类
 * 所属模块：E-01 考试执行模块
 * 对应数据库表：risk_assessment
 *
 * <p>风险评估实体用于记录和管理安全风险事件的评估信息，包括风险识别、
 * 分析、评估、处理等。支持完整的风险评估流程管理。</p>
 *
 * <p>核心功能：
 * - 风险识别：识别和记录潜在的安全风险
 * - 风险分析：深入分析风险的成因和影响
 * - 风险评估：评估风险的严重程度和可能性
 * - 处理建议：提供风险处理建议和措施
 * - 跟踪监控：跟踪风险处理的进展和效果</p>
 *
 * @author System
 * @version 1.0.0
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Entity
@EntityListeners(AuditingEntityListener.class)
public class RiskAssessment {

    /**
     * 主键ID
     */
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    /**
     * 评估ID
     *
     * <p>风险评估的唯一标识符，采用UUID格式生成。</p>
     */
    @Column(name = "assessment_id", nullable = false, length = 32, unique = true)
    private String assessmentId;

    /**
     * 任务ID
     *
     * <p>关联的监控任务ID。</p>
     */
    @Column(name = "task_id", nullable = false, length = 32)
    private String taskId;

    /**
     * 事件ID
     *
     * <p>关联的安全事件ID，可为空。</p>
     */
    @Column(name = "event_id", length = 32)
    private String eventId;

    /**
     * 风险类别
     *
     * <p>风险的类别。
     * 支持的类别：SECURITY（安全）、OPERATION（操作）、TECHNICAL（技术）、BEHAVIOR（行为）、ENVIRONMENT（环境）等</p>
     */
    @Column(name = "risk_category", nullable = false, length = 50)
    private String riskCategory; // TODO: 迁移到外部枚举 RiskCategory

    /**
     * 风险等级
     *
     * <p>风险的等级。
     * 支持的等级：LOW（低）、MEDIUM（中）、HIGH（高）、CRITICAL（关键）、FATAL（致命）</p>
     */
    @Column(name = "risk_level", nullable = false, length = 20)
    private String riskLevel; // TODO: 迁移到外部枚举 RiskLevel

    /**
     * 风险评分
     *
     * <p>风险的综合评分，范围0-100。</p>
     */
    @Column(name = "risk_score", precision = 5, scale = 2)
    private Float riskScore = 0.0f;

    /**
     * 可能性评分
     *
     * <p>风险发生的可能性评分，范围0-10。</p>
     */
    @Column(name = "likelihood_score", precision = 3, scale = 1)
    private Float likelihoodScore = 0.0f;

    /**
     * 影响程度评分
     *
     * <p>风险的影响程度评分，范围0-10。</p>
     */
    @Column(name = "impact_score", precision = 3, scale = 1)
    private Float impactScore = 0.0f;

    /**
     * 风险描述
     *
     * <p>风险的详细描述。</p>
     */
    @Column(name = "risk_description", columnDefinition = "TEXT", length = 1000)
    private String riskDescription;

    /**
     * 风险原因
     *
     * <p>风险产生的原因分析。</p>
     */
    @Column(name = "risk_cause", columnDefinition = "TEXT", length = 1000)
    private String riskCause;

    /**
     * 影响范围
     *
     * <p>风险影响的范围和程度。</p>
     */
    @Column(name = "impact_scope", length = 500)
    private String impactScope;

    /**
     * 评估时间
     *
     * <p>风险评估的时间。</p>
     */
    @Column(name = "assessment_time", nullable = false)
    private LocalDateTime assessmentTime;

    /**
     * 评估状态
     *
     * <p>风险评估的状态。
     * 支持的状态：DRAFT（草稿）、IN_PROGRESS（进行中）、COMPLETED（已完成）、REVIEWED（已复核）、APPROVED（已批准）</p>
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "assessment_status", nullable = false, length = 20)
    private AssessmentStatus assessmentStatus = AssessmentStatus.DRAFT;

    /**
     * 评估者ID
     *
     * <p>进行风险评估的操作者ID。</p>
     */
    @Column(name = "assessor_id", nullable = false, length = 32)
    private String assessorId;

    /**
     * 复核者ID
     *
     * <p>复核风险评估的操作者ID。</p>
     */
    @Column(name = "reviewer_id", length = 32)
    private String reviewerId;

    /**
     * 复核时间
     *
     * <p>复核的时间。</p>
     */
    @Column(name = "review_time")
    private LocalDateTime reviewTime;

    /**
     * 处理建议
     *
     * <p>风险处理的建议措施。</p>
     */
    @Column(name = "treatment_recommendations", columnDefinition = "TEXT", length = 1000)
    private String treatmentRecommendations;

    /**
     * 处理策略
     *
     * <p>风险处理的策略。
     * 支持的策略：AVOID（避免）、MITIGATE（缓解）、TRANSFER（转移）、ACCEPT（接受）</p>
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "treatment_strategy", length = 20)
    private TreatmentStrategy treatmentStrategy;

    /**
     * 控制措施
     *
     * <p>风险控制的具体措施。</p>
     */
    @Column(name = "control_measures", columnDefinition = "TEXT", length = 1000)
    private String controlMeasures;

    /**
     * 监控计划
     *
     * <p>风险监控的计划和安排。</p>
     */
    @Column(name = "monitoring_plan", columnDefinition = "TEXT", length = 1000)
    private String monitoringPlan;

    /**
     * 风险标签
     *
     * <p>JSON格式的风险标签。</p>
     */
    @Column(name = "risk_tags", columnDefinition = "TEXT")
    private String riskTags;

    /**
     * 评估备注
     *
     * <p>评估过程的备注信息。</p>
     */
    @Column(name = "assessment_notes", columnDefinition = "TEXT")
    private String assessmentNotes;

    /**
     * 紧急程度
     *
     * <p>风险处理的紧急程度。</p>
     */
    @Enumerated(EnumType.STRING)
    @Column(name = "urgency_level", length = 20)
    private UrgencyLevel urgencyLevel = UrgencyLevel.NORMAL;

    /**
     * 预计处理时间
     *
     * <p>预计处理风险的时间（小时）。</p>
     */
    @Column(name = "estimated_treatment_hours")
    private Integer estimatedTreatmentHours;

    /**
     * 实际处理时间
     *
     * <p>实际处理风险的时间（小时）。</p>
     */
    @Column(name = "actual_treatment_hours")
    private Integer actualTreatmentHours;

    // ===== 审计字段 =====

    /**
     * 创建时间
     */
    @CreatedDate
    @Column(name = "create_time", nullable = false, updatable = false)
    private LocalDateTime createTime;

    /**
     * 更新时间
     */
    @LastModifiedDate
    @Column(name = "update_time", nullable = false)
    private LocalDateTime updateTime;

    /**
     * 版本号
     */
    @Column(name = "version", nullable = false)
    private Integer version = 1;

    /**
     * 是否删除
     */
    @Column(name = "is_deleted", nullable = false)
    private Boolean isDeleted = false;

    }